package pwd.allen.importBeanDefinitionRegistrar;

import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
import org.springframework.core.type.AnnotationMetadata;
import pwd.allen.entity.Customer;

/**
 *
 * 作用：同ImportSelector，但是更灵活，能自己控制注册BeanDefinitions的行为
 * ImportSelector无法满足时可以用之，例如：要导入的类没法直接实例化，需要注册成FactoryBean时
 * Mybatis的@MapperScan就是用这种方式扫描类并注册BeanDefinition，后面再实例化成代理对象
 *
 * 使用方法：通过@Import指定或者 在ImportSelector的结果中返回；通过@Bean或者xml<bean>的方式是不会生效的
 *
 * 执行时机：
 * 在Beanfactory标准初始化之后，执行BeanFactory后置处理器的时候（invokeBeanFactoryPostProcessors）
 * 会去调用所有的BeanDefinitionRegistryPostProcessor的postProcessBeanDefinitionRegistry方法
 * 其中有一个叫ConfigurationClassPostProcessor的会去检索配置类中引入的Bean定义级别的ImportBeanDefinitionRegistrar，然后遍历调用registerBeanDefinitions
 *
 * @see org.springframework.context.annotation.ConfigurationClassPostProcessor
 * @author pwd
 * @create 2018-11-11 14:31
 **/
public class MyImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {

    /**
     *  逻辑：如果有fruit的beanDifinition则注册customer这个beanDifinition
     *
     * @param importingClassMetadata 当前标注@Import注解的类的所有注解信息 同ImportSelector的第一个入参
     * @param registry  BeanDefinition注册类，通过registerBeanDefinition方法注册
     */
    @Override
    public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
        boolean fruit = registry.containsBeanDefinition("fruit");
        if (fruit) {
            RootBeanDefinition beanDefinition = new RootBeanDefinition(Customer.class);
            registry.registerBeanDefinition("customer", beanDefinition);
        }
    }
}
